'''
ORDER для менеджеров.
Все кодировки можно читать в словари а потом подставлять.
'''
release = 2.01

import os
import sys
import logging                                                                  # запись логов

from datetime import date, timedelta

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtSql import *

sys.path.append(os.getcwd()+'/modules')

from library import field_column, test_release
from connmysql import Db
from login import get_user
from taskopen import TaskOpen

def main():
    """ """
    global user # запись таблицы users залогонившегося пользователя user.поле = значение
    global user_name # таблица users {код : 'фамилия'}
    global main_form # главная форма
    
    app = QApplication(sys.argv)
    app.setStyleSheet(' * {font-family: "Trebuchet MS"; font-size: 13px }')
    
    logging.basicConfig(filename='menager.log',level=logging.DEBUG,
        format = u'%(filename)s[LINE:%(lineno)d]# %(levelname)-8s %(message)s')
        
    # Соединение с БД.
    conn = Db('QMYSQL')
    if not conn.open('designer.ini'):
        quit()

    # Авторизация пользователя.
    user = get_user("designer.ini")
    if not user:
        quit()

    """ Словарь пользователей. Ключ - код, содержимое фамилия. """
    query = QSqlQuery()
    query.exec("SELECT rec_id, surname FROM users;")           
    user_name = {}
    while query.next():
        user_name[query.value(0)] = query.value(1)

    main_form = MainForm()                                                        

    sys.exit(app.exec_())                                                      
    

class MainForm(QDialog):
    """
    В процессе исполнения кода все виджеты формы создаются как локальные переменные.
    Затем закладываются в контейнеры виждеты. Вся итоговая структура локальных
    сохраняется оператором self.setLayout(vbox). Чтобы иметь доступ к элементам
    класса, используем self там, где необходимо.
    """

    def __init__(self, parent=None):
        super().__init__()

        self.create_ui()

    def create_ui(self):

        """ СОЗДАНИЕ ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА """
        
            # ВКЛАДКИ
        self.task_tab = TaskTab()
        self.ready_tab = ReadyTab()
        
            # СБОРКА
        self.tab = QTabWidget()
        self.tab.addTab(self.task_tab, "ОБЩАЯ ОЧЕРЕДЬ")
        self.tab.addTab(self.ready_tab, "ГОТОВЫЕ")
        
            # РАЗМЕЩЕНИЕ
        vbox = QVBoxLayout()
        vbox.addWidget(self.tab)
        self.setLayout(vbox)

            # ОТОБРАЖЕНИЕ
        self.setWindowTitle("ЗАКАЗЫ ДЛЯ ДИЗАЙНЕРА ")
        self.setWindowIcon(QIcon("pict\\order.ico"))
        self.resize(700, 600)
        self.show()                                                               
        
        self.startTimer(60000)

    
    def timerEvent(self,  event):
    
        """ СОБЫТИЯ ПО ТАЙМЕРУ
        --- Рефрешь по таймеру для текущей вкладки.
        --- Проверка на незахваченные задания.
        --- Если задания имеются вывести в системное сообщение.
        """
        
        print('1')
        self.tab_changed(self.tab.currentIndex())
        
        query = QSqlQuery()
        query.exec("SELECT rec_id FROM orders.store "
            "WHERE (date_start IS NULL) AND (data_ready = 1)")
        if not query.size():
            return
        print('2')
        self.tray_icon = QSystemTrayIcon()
        self.tray_icon.setIcon(QIcon('pict\\order.ico'))
        self.tray_icon.show()
        self.tray_icon.showMessage("ОРДЕР", "Есть невыполненные задания.", 
            QSystemTrayIcon.Information, 10000)

            
    def tab_changed(self, index):
    
        """ РЕФРЕШЬ ТАБЛИЦ."""
        
        if index == 0:
            self.task_tab.model.setQuery(self.task_tab.model.query().lastQuery())
        if index == 1:
            self.ready_tab.model.setQuery(self.ready_tab.model.query().lastQuery())


class TaskTab(QWidget):

    def __init__(self, parent=None):
        super().__init__()

        self.setup_ui()
        self.init_ui()


    def setup_ui(self):

        """ СОЗДАНИЕ ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА """
        
            # КНОПКИ
        refresh = QPushButton(" ОБНОВИТЬ ОЧЕРЕДЬ ")
        refresh.clicked.connect(self.refresh_task)

            # ТАБЛИЦЫ
        self.table = QTableView()
        # self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.table.doubleClicked.connect(self.task_open)
        self.table.setContextMenuPolicy(Qt.CustomContextMenu)
        self.table.customContextMenuRequested.connect(self.shortcut_menu)

            # СБОРКА
        hbox = QHBoxLayout()
        hbox.addWidget(refresh)
        hbox.addStretch()

        vbox = QVBoxLayout()
        vbox.addLayout(hbox)
        vbox.addWidget(self.table)
        self.setLayout(vbox)


    def init_ui(self):
            
        """ МОДЕЛЬ ДЛЯ ТАБЛИЦЫ
        --- Создаем собственную модель, чтобы манипулировать построением таблицы.
        --- Заполняе модель информацией.
        --- Создаем словарь полей запроса. Обзываем столбцы. Скрываем ненужные 
            столбцы. Авторесайз колонок под содежимое. """
        
        self.model = TaskModel()

        sql = (
            "SELECT job, date_order, quickly, designer, customer, proportions, rec_id "
            "FROM store "
            "WHERE data_ready = 1 AND date_finish is null "
            "ORDER BY quickly DESC, date_order ASC;")
        self.model.setQuery(sql)
        if self.model.lastError().isValid ():
            logging.critical('TabModel: {}'.format( self.model.lastError().text()))
            quit()

        col = field_column(self.model)
        self.model.setHeaderData(col["job"], Qt.Horizontal, 'Тип')
        self.model.setHeaderData(col["date_order"], Qt.Horizontal, 'Дата')
        self.model.setHeaderData(col["quickly"], Qt.Horizontal, 'Важность')
        self.model.setHeaderData(col["designer"], Qt.Horizontal, 'Дизайнер')
        self.model.setHeaderData(col["customer"], Qt.Horizontal, 'Менеджер')
        self.model.setHeaderData(col["proportions"], Qt.Horizontal, 'Формат')
        self.table.setModel(self.model)
        self.table.setColumnHidden(col['rec_id'], True)
        self.table.resizeColumnsToContents()

        
    def refresh_task(self):
    
        """ ОБНОВЛЕНИЕ ТАБЛИЦЫ """
        
        self.order_tab.model.setQuery(self.order_tab.model.query().lastQuery())


    def task_open(self, index):
    
        """ ОТКРЫТЬ ЗАКАЗ
        --- Находим по модели ключевое поле записи.
        --- Захват задания. 
        --- Если неудача, то возможны варианты: 
        ---     Неожиданно снят заказчиком.
        ---     Уже захвачен другим дизайнером
        ---     Свой.
        --- Открыть запись в отдельной форме. Передать управление в форму.
            После закрытия формы сделать рефрешь таблицы."""
        
        rec_id = self.model.record(index.row()).value('rec_id')
        
        query = QSqlQuery()
        sql = ("UPDATE store SET designer = {}, date_start = NOW() "
            "WHERE (date_start IS NULL) AND (data_ready = 1) AND (rec_id = {})"
            .format(user.rec_id, rec_id))

        query.exec(sql)

        if not query.numRowsAffected():
            sql = ("SELECT data_ready, designer FROM store WHERE rec_id = {}".format(rec_id))       
            query.exec(sql)
            query.next()
            data_ready = query.value(0)
            designer = query.value(1)

            if not data_ready:
                QMessageBox.warning(self,"ЗАДАНИЕ СНЯТО",
                    "Выберете другое задание, подготовленное для исполнения.")
                return

            if designer != user.rec_id:
                QMessageBox.warning(self,"УЖЕ ВЫПОЛНЯЕТСЯ",
                    "Выберете другое задание, подготовленное для исполнения.")
                return
            
        module = TaskOpen(main_form, rec_id)
        module.exec_()
        self.model.setQuery(self.model.query().lastQuery())

        
    def shortcut_menu(self, pos):
    
        """ КОНТЕКСТНОЕ МЕНЮ """
        
        menu = QMenu(self)
        menu.addAction("Сменить дизайнера", self.replace_designer)
        menu.exec_(QCursor.pos())

        
    def replace_designer(self):
    
        """ СМЕНИТЬ ДИЗАЙНЕРА
        --- Номер текущей строки берём из таблицы. По номеру строки находим в
            модели значение ключевого поля.
        --- Уже заменен.
        --- Некого менять.
        --- Меняем дизайнера."""
        
        row_table = self.table.currentIndex().row()                              
        rec_id = self.model.record(row_table).value('rec_id')
        designer = self.model.record(row_table).value('designer')
        
        if designer == user.rec_id:
            return
            
        if not designer:
            QMessageBox.warning(self, "НЕТ ДИЗАЙНЕРА",
                "Дизайнера можно поменять только у заказа, который начали выполнять.")
            return
          
        sql = ("UPDATE store SET date_start = NOW(), designer = {} "
            "WHERE rec_id = {}"
            .format(user.rec_id, rec_id))
        query = QSqlQuery()
        query.exec(sql)
        self.refresh_task()


class TaskModel(QSqlQueryModel):

    def __init__(self, parent=None):
        super().__init__()                                                      # запускаем init родительского класса

        self.green = QColor.fromRgb(193, 255, 193)
        self.red = QColor.fromRgb(255, 215, 215)


    def data(self, item, role):
        
        global user_name
        """ Передается элемент (QModelIndex) который прорисовывается и роль. """

        value = super(TaskModel, self).data(item, role)                         
        row = item.row()

        # ОТОБРАЖАЕМАЯ ИНФОРМАЦИЯ
        if role == Qt.DisplayRole:

            """ СТАТУС."""
            if item.column() == self.record().indexOf("status"):                # статус заказа
                if self.record(row).value('date_finish'):
                    value = 'ГОТОВ'
                if not self.record(row).value('data_ready'):
                    value = 'ЗАБЫТЫЙ'
                if self.record(row).value('data_ready') and not self.record(row).value('date_start'):
                    value = 'В ОЧЕРЕДИ'
                if self.record(row).value('date_start') and not self.record(row).value('date_finish'):
                    value = 'ВЫПОЛНЯЕТСЯ'

            """ ТИП."""
            if item.column() == self.record().indexOf("job"):                   # тип заказа
                if value == 0:
                    value = 'модуль'
            """ ВАЖНОСТЬ."""
            if item.column() == self.record().indexOf("quickly"):               # важность
                if value == 1:
                    value = 'СРОЧНО'
                else:
                    value = ''
            """ МЕНЕДЖЕР."""
            if item.column() == self.record().indexOf("customer"):              
                if value in user_name:
                    value = user_name[value]
                else:
                    value = ''
            """ ДИЗАЙНЕР."""
            if item.column() == self.record().indexOf("designer"):              
                if value in user_name:
                    value = user_name[value]
                else:
                    value = ''

        # ВЫРАВНИВАНИЕ
        if role == Qt.TextAlignmentRole:
            # if item.column() == 2:
                # return int(Qt.AlignRight | Qt.AlignVCenter)
            # else:
                return int(Qt.AlignCenter | Qt.AlignVCenter)

        # ЦВЕТ ТЕКСТА
        if role == Qt.TextColorRole:
            if item.column() == self.record().indexOf("status"):
                if self.record(row).value('date_finish'):
                    return QColor(Qt.blue)
                if (self.record(row).value('date_start')) and (not self.record(row).value('date_finish')):
                    return QColor(Qt.green)
            # if item.column() == self.record().indexOf("status"):
                # return QColor(Qt.blue)
            if item.column() == self.record().indexOf("quickly"):
                return QColor(Qt.red)

        # ЦВЕТ ФОНА
        # if role == Qt.BackgroundRole:
            # status = ''
            # if self.record(row).value('data_ready'):
                # status = 'Забытый'
            # row = index.row()
            # if (self.record(row).value('date_start') and
                # not self.record(row).value('date_finish')):
                # return QBrush(self.green)
            # if (self.record(row).value('data_ready') and
                # not self.record(row).value('date_start')):
                # return QBrush(self.red)

        return value


class ReadyTab (QWidget):


    """ Показываем выполненные заказы за три рабочих дня """
    # dat = date.today()
    # if dat.weekday() == 0:                                                  # понедельник
        # days = 4
    # elif dat.weekday() == 1:                                                # вторник
        # days = 5
    # else:
        # days = 3
    # dat = dat - timedelta(days=3)
    # dat = dat.strftime('%Y-%m-%d')

    def __init__(self, parent=None):
        super().__init__()                                                      # запускаем init родительского класса

        self.setup_ui()
        self.init_ui()


    def setup_ui(self):

        """ СОЗДАНИЕ ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА """
        
            # ТАБЛИЦЫ
        self.table = QTableView()
        # self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
##        self.table.doubleClicked.connect(self.double_clik)
        self.table.setContextMenuPolicy(Qt.CustomContextMenu)
##        self.table.customContextMenuRequested.connect(self.shortcut_menu)

            # СБОРКА
        vbox = QVBoxLayout()
        vbox.addWidget(self.table)
        self.setLayout(vbox)

        
    def init_ui(self):

        """ МОДЕЛЬ ДЛЯ ТАБЛИЦЫ
        --- Создаем собственную модель, чтобы манипулировать построением таблицы.
        --- Заполняе модель информацией.
        --- Создаем словарь полей запроса. Обзываем столбцы. Подавляем ненужные.
        """
        
        self.model = ReadykModel()

        sql = (
            "SELECT date_order, num_asu_new, customer, designer, rec_id "
            "FROM store "
            "WHERE (date_finish IS NOT NULL) AND (DATEDIFF(NOW(),date_finish) < 1) "
            "ORDER BY date_order ASC")
        self.model.setQuery(sql)
        if self.model.lastError().isValid ():
            logging.critical('TabModel: {}'.format( self.model.lastError().text()))
            quit()

        col = field_column(self.model)
        self.model.setHeaderData(col["date_order"], Qt.Horizontal, 'Дата')
        self.model.setHeaderData(col["num_asu_new"], Qt.Horizontal, '№ АСУ')
        self.model.setHeaderData(col["customer"], Qt.Horizontal, 'Менеджер')
        self.model.setHeaderData(col["designer"], Qt.Horizontal, 'Дизайнер')
        self.table.setModel(self.model)
        self.table.setColumnHidden(col['rec_id'], True)
        self.table.resizeColumnsToContents()
    

class ReadykModel(QSqlQueryModel):

    def __init__(self, parent=None):
        super().__init__()                                                      # запускаем init родительского класса

        self.green = QColor.fromRgb(193, 255, 193)
        self.red = QColor.fromRgb(255, 215, 215)


    def data(self, item, role):
        """ Передается элемент (QModelIndex) который прорисовывается и роль. """

        value = super(ReadykModel, self).data(item, role)                        # Returns the value for the specified item and role.

        # ОТОБРАЖАЕМАЯ ИНФОРМАЦИЯ
        if role == Qt.DisplayRole:

            row = item.row()
            """ СТАТУС."""
            if item.column() == self.record().indexOf("status"):                # статус заказа
                if not self.record(row).value('data_ready'):
                    value = 'ЗАБЫТЫЙ'
                if self.record(row).value('data_ready') and not self.record(row).value('date_start'):
                    value = 'В ОЧЕРЕДИ'
                if self.record(row).value('date_start') and not self.record(row).value('date_finish'):
                    value = 'ВЫПОЛНЯЕТСЯ'
                if self.record(row).value('date_finish'):
                    value = 'ГОТОВ'

            """ ТИП."""
            if item.column() == self.record().indexOf("job"):                   # тип заказа
                if value == 0:
                    value = 'модуль'
            """ ВАЖНОСТЬ."""
            if item.column() == self.record().indexOf("quickly"):               # важность
                if value == 1:
                    value = 'СРОЧНО'
                else:
                    value = ''
            """ МЕНЕДЖЕР."""
            if item.column() == self.record().indexOf("customer"):              
                if value in user_name:
                    value = user_name[value]
                else:
                    value = ''
            """ ДИЗАЙНЕР."""
            if item.column() == self.record().indexOf("designer"):              
                if value in user_name:
                    value = user_name[value]
                else:
                    value = ''

        # ВЫРАВНИВАНИЕ
        if role == Qt.TextAlignmentRole:
            return int(Qt.AlignCenter | Qt.AlignVCenter)

        # ЦВЕТ ТЕКСТА
        if role == Qt.TextColorRole:
            if item.column() == self.record().indexOf("status"):
                return QColor(Qt.blue)
            if item.column() == self.record().indexOf("quickly"):
                return QColor(Qt.red)

        # ЦВЕТ ФОНА
        # if role == Qt.BackgroundRole:
            # status = ''
            # if self.record(row).value('data_ready'):
                # status = 'Забытый'
            # row = index.row()
            # if (self.record(row).value('date_start') and
                # not self.record(row).value('date_finish')):
                # return QBrush(self.green)
            # if (self.record(row).value('data_ready') and
                # not self.record(row).value('date_start')):
                # return QBrush(self.red)

        return value

    
if __name__ == '__main__':                                               
    main()

